package usercenter

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"time"
)

var _ UserBanModel = (*customUserBanModel)(nil)

type (
	// UserBanModel is an interface to be customized, add more methods here,
	// and implement the added methods in customUserBanModel.
	UserBanModel interface {
		userBanModel
		InsertTrans(ctx context.Context, tx sqlx.Session, data *UserBan) (sql.Result, error)
		UpdateBanState(ctx context.Context, tx sqlx.Session, uid int64, banAdminUid int64, banReason string, banHours int64, autoUnbanTime *time.Time) error
		UpdateUnbanState(ctx context.Context, tx sqlx.Session, uid int64, unbanAdminUid int64) error
	}

	customUserBanModel struct {
		*defaultUserBanModel
	}
)

// NewUserBanModel returns a model for the database table.
func NewUserBanModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) UserBanModel {
	return &customUserBanModel{
		defaultUserBanModel: newUserBanModel(conn, c, opts...),
	}
}

func (m *customUserBanModel) InsertTrans(ctx context.Context, tx sqlx.Session, data *UserBan) (sql.Result, error) {
	mumbaiUserBanUidKey := fmt.Sprintf("%s%v", cacheMumbaiUsercenterUserBanUidPrefix, data.Uid)
	ret, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, userBanRowsExpectAutoSet)
		return tx.ExecCtx(ctx, query, data.Uid, data.BanHours, data.BanReason, data.AutoUnbanTime, data.BanAdminUid, data.UnbanAdminUid)
	}, mumbaiUserBanUidKey)
	return ret, err
}

func (m *customUserBanModel) UpdateBanState(ctx context.Context, tx sqlx.Session, uid int64, banAdminUid int64, banReason string, banHours int64, autoUnbanTime *time.Time) error {
	mumbaiUsercenterUserBanUidKey := fmt.Sprintf("%s%v", cacheMumbaiUsercenterUserBanUidPrefix, uid)
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set auto_unban_time = ?, ban_hours = ?, ban_reason = ?, ban_admin_uid = ? where uid = ?", m.table)
		return tx.ExecCtx(ctx, query, autoUnbanTime, banHours, banReason, banAdminUid, uid)
	}, mumbaiUsercenterUserBanUidKey)
	if err != nil {
		return err
	}
	return nil
}

func (m *customUserBanModel) UpdateUnbanState(ctx context.Context, tx sqlx.Session, uid int64, unbanAdminUid int64) error {
	mumbaiUsercenterUserBanUidKey := fmt.Sprintf("%s%v", cacheMumbaiUsercenterUserBanUidPrefix, uid)
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set unban_admin_uid = ? where uid = ?", m.table)
		return tx.ExecCtx(ctx, query, unbanAdminUid, uid)
	}, mumbaiUsercenterUserBanUidKey)
	if err != nil {
		return err
	}
	return nil
}
